﻿using Abp.Application.Services;
using Abp.Linq.Extensions;
using Hangfire;
using Hicap.QRCodeWarehouse.Application.Dto;
using Hicap.QRCodeWarehouse.Core;
using Hicap.QRCodeWarehouse.Core.Identity;
using Hicap.QRCodeWarehouse.Core.Managers;
using Hicap.QRCodeWarehouse.Core.Models.DbSet;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hicap.QRCodeWarehouse.Application.App
{
    /// <summary>
    /// Warhouse monitor service
    /// </summary>
    [HicapAuthorize]
    public class WarhouseMonitorAppService : IApplicationService
    {
        private readonly IMonitorManager _monitorManager;

        public WarhouseMonitorAppService(IMonitorManager monitorManager)
        {
            _monitorManager = monitorManager;
        }

        /// <summary>
        /// Get current monitor infos
        /// </summary>
        /// <returns></returns>
        public async Task GetWarhouseMonitorInfos()
        {
            await _monitorManager.GetMonitorInfos(0);
        }

        /// <summary>
        /// Get history monitor infos
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<MonitorHistory>> QueryWarhouseMonitorInfos(MonitorQueryDto input)
        {
            IQueryable<MonitorHistory> query = _monitorManager.GetMonitorInfos(new Tuple<DateTime?, DateTime?>(input.MinDateTime, input.MaxDateTime), input.RecordTime);

            List<MonitorHistory> result = new List<MonitorHistory>();

            if (input.IsOnlyRecordTime)
            {
                foreach (MonitorHistory item in query
                    .OrderByDescending(x => x.RecordTime)
                    .PageBy(input))
                {
                    result.Add(new MonitorHistory() { RecordTime = item.RecordTime, Id = item.Id });
                }

                return result;
            }

            result = await query
                .OrderByDescending(x => x.RecordTime)
                .PageBy(input).ToListAsync();

            return result;
        }

        /// <summary>
        /// Change monitor info interval
        /// </summary>
        /// <param name="input">MonitorEditDto</param>
        /// <returns></returns>
        public async Task ChangeWarhouseMonitorInterval(MonitorEditDto input)
        {
            await Task.Run(() =>
            {
                RecurringJob.RemoveIfExists(SysConsts.MonitorRecurringJobName);
                //Add or update timed job
                RecurringJob.AddOrUpdate<IMonitorManager>(SysConsts.MonitorRecurringJobName, x => x.GetMonitorInfos(1), Cron.HourInterval(input.IntervalHour));
            });
        }
    }
}